<?php
/**
 * 管理员控制器
 *
 * @author jonwang
 *
 */
class Controller_MyQEE__Administrator__Index extends Controller_Admin
{
    public function action_default()
    {
        $this->quick_menu = array(
            'administrator/add' => '添加管理员',
            'administrator/group/' => '权限组列表',
            'administrator/group/add' => '添加权限组',
        );
        $view = new View('admin/administrator/list');

        $model_administrator = new Model_Admin_Administrator();

        $only_list_my_group_user = false;
        $is_super = $this->session()->member()->perm()->is_super_perm();
        if ( $is_super )
        {
            $project = null;
        }
        else
        {
            $project = Core::$project;
            if ( !$this->session()->member()->perm()->is_own('administrator.view_user_info') )
            {
                if ( $this->session()->member()->perm()->is_own('administrator.view_self_group_user_info') )
                {
                    $only_list_my_group_user = true;
                }
                else
                {
                    $this->message('您不具备此权限',-1);
                }
            }
        }

        $count = $model_administrator->total_count($project , $only_list_my_group_user);

        if ($count)
        {
            $pageconfig = Core::config('admin/pagination');
            $pageconfig['total_items'] = $count;

            $pagination = new Pagination($pageconfig);

            $list = $model_administrator->get_aministrator_list($project, $only_list_my_group_user, $pagination->get_offset() , $pagination->get_items_per_page() );
            $view->list = $list;
            $view->pagehtml = $pagination->render();
        }

        $view->is_super = $is_super;
        $view->render();
    }

    public function action_change_password( $member_id = 0)
    {
        $this->page_title = '修改密码';

        $member_id = (int)$member_id;

        $msg = '';
        if (Request::$method=='POST')
        {
            # 提交数据
            try {

                $this->check_password($_POST);

                if ( !$member_id>0 )
                {
                    $member = $this->session()->member();
                }
                else
                {
                    $model_admin = new Model_Admin_Administrator();
                    $member = $model_admin->get_by_id($member_id);
                    if (!$member)
                    {
                        throw new Exception('指定的用户ID不存在');
                    }
                }

                $this->check_auth_for_edit_password($member);

                if ( $this->do_change_password($member,$_POST) )
                {
                    $msg = '密码修改成功';
                    $code = 1;
                }
            }
            catch (Exception $e)
            {
                $code = $e->getCode();
                $msg = $e->getMessage();
            }

            if (Request::$is_ajax)
            {
                $this->message($msg,$code);
            }
        }

        try
        {
            if ( !$member_id>0 )
            {
                $member_id = $this->session()->member()->id;
                $member = $this->session()->member();
            }
            else
            {
                $model_admin = new Model_Admin_Administrator();
                $member = $model_admin->get_by_id($member_id);
                if (!$member)
                {
                    throw new Exception('指定的用户ID不存在');
                }
            }

            $this->check_auth_for_edit_password($member);
        }
        catch (Exception $e)
        {
            $this->message($msg,$code);
        }

        $view = new View('admin/administrator/change_password');
        $view->member_id = $member_id;
        $view->msg = $msg;
        $view->render();
    }

    public function action_add()
    {
        $this->action_edit();
    }

    public function action_edit( $member_id=0 )
    {
        $this->quick_menu = array(
            'administrator/' => '管理员列表',
            'administrator/group/' => '权限组列表',
            'administrator/group/add' => '添加权限组',
        );
        $this->page_title = $member_id>0?'修改管理员':'添加管理员';

        $orm_member = new ORM_Admin_Member_Finder();
        if ( $member_id>0 )
        {
            $member = $orm_member->get_by_id($member_id);

            try
            {
                $this->check_auth_for_edit($member);
            }
            catch (Exception $e)
            {
                $this->message($e->getMessage(),$e->getCode());
            }
        }
        else
        {
            $member = $orm_member->create();

            try
            {
                $this->check_auth_for_add($member);
            }
            catch (Exception $e)
            {
                $this->message($e->getMessage(),$e->getCode());
            }
        }

        if ( Session::instance()->member()->perm()->is_super_perm() )
        {
            $model_admin = new Model_Admin_Administrator();
            $groups = $model_admin->get_group_list(null,0,0);
            $this->show_edit_perm = true;
        }
        else
        {
            if ( $member->id>0 )
            {
                if ( $this->check_is_over_perm( $member ) )
                {
                    $over_perm = true;
                }
                else
                {
                    $over_perm = false;
                }
            }
            else
            {
                $over_perm = true;
            }
            if ( $over_perm )
            {
                $groups = Session::instance()->member()->all_groups();

                if ( $member->id>0 )
                {
                    if ( $this->session()->member()->perm()->is_super_perm() || !array_diff( $this->session()->member()->group_ids , $member->group_ids ) )
                    {
                        # 超管或者该用户所在的权限组操作者也都在
                        $this->show_edit_perm = true;
                    }
                    else
                    {
                        $this->show_edit_perm = false;
                    }
                }
                else
                {
                    $this->show_edit_perm = true;
                }
            }
            else
            {
                $this->show_edit_perm = false;
            }
        }

        if ( Request::$method=='POST' )
        {
            $this->edit_save($member);
        }

        $view = new View('admin/administrator/form');

        $view->member = $member;
        $view->title = $this->page_title;
        $view->groups = $groups;
        $view->show_edit_perm = $this->show_edit_perm;

        $view->render();
    }

    public function action_edit_perm_form( $member_id=0 )
    {
        $group_ids = explode( ',', $_GET['group_ids'] );
        $orm_member = new ORM_Admin_Member_Finder();
        if ( $member_id>0 )
        {
            $member = $orm_member->get_by_id($member_id);
        }
        else
        {
            $member = $orm_member->create();
        }

        $orm_group = new ORM_Admin_MemberGroup_Finder();
        $groups = $orm_group->in('id', $group_ids)->find();


        $perm_setting = array();
        foreach ($groups as $item)
        {
            # 合并权限
            $perm_setting = array_merge_recursive($perm_setting,$item->perm_setting);
        }

        $perm = new Permission($perm_setting);

        View::factory('/admin/administrator/perm_form',array('perm'=>$perm,'member'=>$member))->render();
    }

    /**
     * 屏蔽用户
     *
     * @param int $member_id
     */
    public function action_shield( $member_id )
    {
        $orm_member = new ORM_Admin_Member_Finder();
        $member = $orm_member->get_by_id($member_id);

        if (!$member)
        {
            $this->message('指定的用户不存在');
        }

        try {
            $this->check_auth_for_shield( $member );
        }
        catch(Exception $e)
        {
            $this->message($e->getMessage(),$e->getCode());
        }

        $member->shielded = 1;

        $status = $member->update();
        if ($status)
        {
            $this->message('保存成功',1);
        }
        else
        {
            $this->message('未更新数据',0);
        }
    }

    /**
     * 解除屏蔽用户
     *
     * @param int $member_id
     */
    public function action_liftshield( $member_id )
    {
        $orm_member = new ORM_Admin_Member_Finder();
        $member = $orm_member->get_by_id($member_id);

        if (!$member)
        {
            $this->message('指定的用户不存在');
        }

        try {
            $this->check_auth_for_liftshield( $member );
        }
        catch(Exception $e)
        {
            $this->message($e->getMessage(),$e->getCode());
        }

        $member->shielded = 0;

        $status = $member->update();
        if ($status)
        {
            $this->message('保存成功',1);
        }
        else
        {
            $this->message('未更新数据',0);
        }
    }

    public function action_delete( $member_id )
    {
        $member_id = (int)$member_id;
        if (!$member_id>0)
        {
            $this->message('参数错误');
        }

        $orm_member = new ORM_Admin_Member_Finder();
        $member = $orm_member->get_by_id($member_id);

        if (!$member)
        {
            $this->message('指定的用户不存在或已被删除');
        }

        try {
            $this->check_auth_for_delete( $member );
        }
        catch(Exception $e)
        {
            $this->message($e->getMessage(),$e->getCode());
        }

        $status = $member->delete();

        if ($status)
        {
            $this->message('删除成功' , 1);
        }
        else
        {
            $this->message('未删除数据' , 0);
        }
    }

    /**
     * 检查秘密是否符合要求
     *
     * @param array $data 通常是POST的数据
     */
    protected function check_password($data)
    {
        if (empty($data['new_password']))
        {
            throw new Exception('新密码不能空',-1);
        }
        if (strlen($data['new_password'])<6)
        {
            throw new Exception('新密码太短',-1);
        }
        if ( $data['new_password'] != $data['new_password_2'] )
        {
            throw new Exception('两次输入的密码不一致',-1);
        }
        return true;
    }

    protected function do_change_password(ORM_Admin_Member_Data $member,$data )
    {
        if ( $member->id>0 && $member->id==Session::instance()->member()->id )
        {
            # 修改自己的密码
            if ( !Session::instance()->member()->check_password($data['old_password']) )
            {
                throw new Exception('旧密码验证失败',-1);
            }
        }

        $status = $member->change_password($data['new_password']);

        if ( !$status )
        {
            throw new Exception('未修改密码。');
        }
        else
        {
            return true;
        }
    }

    protected function edit_save(ORM_Admin_Member_Data $member)
    {
        try {
            if (!$member)
            {
                throw new Exception('指定的ID的用户不存在', -1);
            }

            $member->nickname = $_POST['nickname'];

            if ( $this->show_edit_perm )
            {
                # 处理所在组
                if ( !$_POST['group_ids'] || !is_array($_POST['group_ids']) )
                {
                    throw new Exception('至少指定一个权限组', -1);
                }
                $old_groups = (array)$member->group_ids;
                $new_groups = (array)$_POST['group_ids'];
                # 添加的权限
                $new_diff_group = array_diff($new_groups , $old_groups);
                # 删除掉的权限
                $del_diff_group = array_diff($old_groups , $new_groups);
                # 差别的权限
                $diff_group = array_merge($new_diff_group , $del_diff_group);

                if ( $diff_group )
                {
                    # 新旧管理组不一样
                    $default_group_id = (int)$_POST['default_group_id'];
                    if ($default_group_id>0)
                    {
                        # 处理默认权限组，默认权限组应该排在第一个
                        array_unshift($new_groups,$default_group_id);
                        $new_groups = array_unique($new_groups);
                    }

                    $orm_group = new ORM_Admin_MemberGroup_Finder();
                    $groups = $orm_group->in('id', $new_groups)->find();

                    $new_group_perm_setting = array();
                    foreach ($groups as $item)
                    {
                        # 合并权限
                        $new_group_perm_setting = array_merge_recursive($new_group_perm_setting,$item->perm_setting);
                    }

                    # 修改权限组需要验证一下新权限
                    Controller_Administrator__Index::check_perm_data( $new_group_perm_setting );

                    if ( $member->id )
                    {
                        # 修改用户权限
                        $pm1 = 'administrator.edit_new_user';            //全局
                        $pm2 = 'administrator.edit_self_group_user';     //本组
                    }
                    else
                    {
                        # 添加用户权限
                        $pm1 = 'administrator.add_new_user';
                        $pm2 = 'administrator.add_self_group_user';
                    }
                    # 检查权限
                    if ( !$this->session()->member()->perm()->is_own($pm1) && $this->session()->member()->perm()->is_own($pm2) )
                    {
                        if ( $diff_group && array_diff( $diff_group , $this->session()->member()->group_ids ) )
                        {
                            throw new Exception('您为此用户设定的新权限组不在您的权限范围内', -1);
                        }
                    }

                    # 修改权限组
                    $member->group_ids = $new_groups;
                }

                # 处理权限
                if ( $this->check_auth_for_perm($member) )
                {
                    $perm_setting = Controller_Administrator__Index::check_perm_data((array)$_POST['perm_setting']);

                    # 设置数据
                    $member->perm_setting = $perm_setting;
                }

                if ( $member->id>0 && !$this->check_is_over_perm( $member ) )
                {
                    throw new Exception('你不具备该用户某些权限，所以您不能修改该用户权限。', -1);
                }
            }

            $transaction = $member->orm()->driver()->transaction();
            $transaction->start();

            $this->edit_other_info($member);

            # 保存数据
            if ( $member->id>0 )
            {
                # 修改用户
                $member->update();
            }
            else
            {
                # 创建新用户

                if ( !$_POST['username'] )
                {
                    throw new Exception('用户名不能空', -1);
                }
                if ( !$_POST['new_password'] )
                {
                    throw new Exception('密码不能空', -1);
                }
                if (  $_POST['new_password'] != $_POST['new_password_2'] )
                {
                    throw new Exception('两次输入的密码不一致，请重新确认', -1);
                }
                $model_admin = new Model_Admin_Administrator();
                if ( $model_admin->get_by_username($_POST['username']) )
                {
                    throw new Exception('此用户名已存在，请换一个', -1);
                }

                # 设置用户名
                $member->username = $_POST['username'];

                # 只有在创建用户的时候才可以设置所属项目
                if ( isset($_POST['project']) && $this->session()->member()->perm()->is_super_perm() )
                {
                    $member->project = $_POST['project'];
                }
                else
                {
                    $member->project = Core::$project;
                }

                $member->password = '';
                $member->shielded = 0;
                $member->notepad = '';

                # 创建用户数据
                $member->insert();

                # 插入后再修改密码
                $member->change_password($_POST['new_password']);
            }

            $transaction->commit();
            $msg = '操作成功';
            $code = 1;
        }
        catch (Exception $e)
        {
            if ($transaction)
            {
                $transaction->rollback();
            }
            $code = $e->getCode();
            $msg = $e->getMessage();
        }

        if (Request::$is_ajax)
        {
            $this->message($msg,$code);
        }
    }

    /**
     * 修改其他信息
     *
     * @param ORM_Admin_Member_Data $member
     */
    protected function edit_other_info(ORM_Admin_Member_Data $member)
    {
        return true;
    }

    /**
     * 检验操作者权限是否高于此用户
     *
     * @param ORM_Admin_Member_Data $member
     */
    protected function check_is_over_perm(ORM_Admin_Member_Data $member)
    {
        # 是否超管
        if ( $this->session()->member()->perm()->is_super_perm() )
        {
            return true;
        }

        $my_perm_setting = $this->session()->member()->perm()->get_setting();
        $member_perm_setting = $member->perm()->get_setting();

        $tmp_perm = array_merge_recursive($my_perm_setting,$member_perm_setting);

        if ( $my_perm_setting == $tmp_perm )
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * 检查用户是否有操作用户权限的权限
     *
     * @param ORM_Admin_Member_Data $gourp
     * @return boolean
     */
    protected function check_auth_for_perm(ORM_Admin_Member_Data $member)
    {
        $member_perm = $this->session()->member()->perm();
        if ( $member_perm->is_super_perm() )
        {
            # 超管
            return true;
        }

        if ( $member->id > 0 )
        {
            # 修改组
            if ( $member_perm->is_own('administrator.change_user_perm') )
            {
                return true;
            }
        }
        else
        {
            #添加
            if ( $member_perm->is_own('administrator.add_new_user') || $member_perm->is_own('administrator.add_self_group_user') )
            {
                return true;
            }
        }

        return false;
    }

    /**
     * 整理并检查权限数据
     *
     * @param array $perm
     * @throws Exception
     * @return array
     */
    public static function check_perm_data( $perm )
    {
        $my_perm = Session::instance()->member()->perm();
        $perm_config = Core::config('admin/permission');

        if ( Session::instance()->member()->perm()->is_super_perm() )
        {
            $is_super = true;
        }
        else
        {
            $is_super = false;
        }

        # 提交的权限中有超管权限
        if ( isset($perm['_super_admin']) )
        {
            if ($is_super)
            {
                # 当前操作用户是超管
                return array('_super_admin'=>true);
            }
            else
            {
                # 当前操作用户非超管
                unset($perm['_super_admin']);
            }
        }

        foreach ( $perm as $key => $item )
        {
            if ( is_array($item) )
            {
                foreach ( $perm as $k => $v )
                {
                    if ( isset($perm_config[$key][$k]) )
                    {
                        # 忽略掉没有的项目
                        unset($perm[$key][$k]);
                        continue;
                    }
                    else
                    {
                        $perm[$key][$k] = 1;
                    }

                    # 判断当前用户是否有此权限，超管就不用检查了
                    if ( !$is_super && !$my_perm->is_own($key.'.'.$k) )
                    {
                        # 权限名称
                        $pname = $perm_config[$key][$k];
                        if ( is_array($pname) )
                        {
                            $pname = (string)$pname['innerHTML'];
                        }
                        throw new Exception('您不具备此权限:“'.$pname.'”，操作已取消', -1);
                    }
                }
            }
        }

        return $perm;
    }

    /**
     * 检查用户是否具有屏蔽指定用户的权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_shield(ORM_Admin_Member_Data $member)
    {
        if ( !$this->session()->member()->perm()->is_own('administrator.shield_user') )
        {
            # 没有权限屏蔽权限
            $diff_group = array_diff( $member->group_ids , $this->session()->member()->group_ids );
            if ( $diff_group || !$this->session()->member()->perm()->is_own('administrator.shield_self_group_user') )
            {
                # 不在一个组里，或者不拥有组的屏蔽权限
                throw new Exception('您不具备屏蔽该用户的权限',-1);
            }
        }

        if ( $member->id == $this->session()->member()->id )
        {
            throw new Exception('您不可屏蔽自己',-1);
        }

        if ( $member->perm()->is_super_perm() && !$this->session()->member()->perm()->is_super_perm() )
        {
            # 一个非超管人士视图屏蔽一个超管
            throw new Exception('您不具备屏蔽超管的权限',-1);
        }

        return true;
    }

    /**
     * 检查用户是否具有解除屏蔽指定用户的权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_liftshield(ORM_Admin_Member_Data $member)
    {
        if ( !$this->session()->member()->perm()->is_own('administrator.liftshield_user') )
        {
            # 没有解除权限屏蔽权限
            $diff_group = array_diff( $member->group_ids , $this->session()->member()->group_ids );
            if ( $diff_group || !$this->session()->member()->perm()->is_own('administrator.liftshield_self_group_user') )
            {
                # 待删除用户所在组中含有操作者中不存在的组，或者不拥有组的相应权限
                throw new Exception('您不具备解除屏蔽该用户的权限',-1);
            }
        }

        if ( $member->perm()->is_super_perm() && !$this->session()->member()->perm()->is_super_perm() )
        {
            # 一个非超管人士视图解除屏蔽一个超管
            throw new Exception('您不具备解除屏蔽超管的权限',-1);
        }

        return true;
    }

    /**
     * 检查用户是否有删除权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_delete(ORM_Admin_Member_Data $member)
    {
        if ( !$this->session()->member()->perm()->is_own('administrator.delete_user') )
        {
            # 没有删除用户权限
            $diff_group = array_diff( $member->group_ids , $this->session()->member()->group_ids );
            if ( $diff_group || !$this->session()->member()->perm()->is_own('administrator.delete_self_group_user') )
            {
                # 待删除用户所在组中含有操作者中不存在的组，或者不拥有组的相应权限
                throw new Exception('您不具备删除该用户的权限' , -1);
            }
        }

        if ( $member->perm()->is_super_perm() && !$this->session()->member()->perm()->is_super_perm() )
        {
            # 一个非超管人士视图解除屏蔽一个超管
            throw new Exception('您不具备删除超管的权限',-1);
        }

        return true;
    }

    /**
     * 检查用户是否有添加权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_add(ORM_Admin_Member_Data $member)
    {
        if ( !$this->session()->member()->perm()->is_own('administrator.add_new_user') )
        {
            if ( !$this->session()->member()->perm()->is_own('administrator.add_self_group_user') )
            {
                $this->message('您不具备此权限',-1);
            }
        }

        return true;
    }

    /**
     * 检查用户是否有修改用户权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_edit(ORM_Admin_Member_Data $member)
    {
        if ( $member->id && $member->id==$this->session()->member()->id )
        {
            if ( $this->session()->member()->perm()->is_own('administrator.edit_self_info') )
            {
                # 修改自己的信息
                return true;
            }
        }

        if ( !$this->session()->member()->perm()->is_own('administrator.edit_user_info') )
        {
            # 不具备组管理权限
            if ( $this->session()->member()->perm()->is_own('administrator.edit_self_group_user_info') )
            {
                # 拥有所在组管理权限
                if ( array_diff($member->group_ids , $this->session()->member()->group_ids) )
                {
                    # 没有相同的组
                    $this->message('您操作的用户拥有你不具备的权限组，所有你无法操作此用户',-1);
                }
            }
            else
            {
                $this->message('您不具备修改此用户的权限',-1);
            }
        }

        if ( $member->perm()->is_super_perm() && !$this->session()->member()->perm()->is_super_perm() )
        {
            # 一个非超管人士视图解除屏蔽一个超管
            throw new Exception('您不具备操作超管的权限',-1);
        }

        return true;
    }

    /**
     * 检查用户是否有修改用户密码权限
     *
     * @param ORM_Admin_Member_Data $member
     * @throws Exception
     *
     * @return boolean
     */
    protected function check_auth_for_edit_password(ORM_Admin_Member_Data $member)
    {
        if ( $member->id && $member->id==$this->session()->member()->id )
        {
            if ( $this->session()->member()->perm()->is_own('administrator.edit_self_password') )
            {
                # 修改自己的密码
                return true;
            }
        }

        if ( !$this->session()->member()->perm()->is_own('administrator.change_user_password') )
        {
            # 不具备组管理权限
            if ( $this->session()->member()->perm()->is_own('administrator.delete_self_group_user') )
            {
                # 拥有所在组管理权限
                if ( array_diff($member->group_ids , $this->session()->member()->group_ids) )
                {
                    # 没有相同的组
                    $this->message('您操作的用户拥有你不具备的权限组，所有你无法修改此用户密码',-1);
                }
            }
            else
            {
                $this->message('您不具备修改此用户密码的权限',-1);
            }
        }

        if ( $member->perm()->is_super_perm() && !$this->session()->member()->perm()->is_super_perm() )
        {
            # 一个非超管人士视图解除屏蔽一个超管
            throw new Exception('您不具备修改超管密码的权限',-1);
        }

        return true;
    }
}